/**
 * 重载局部（类内部）operator new
 * 使用new分配某个重载了new的累的对象空间时，先调用new的重载函数，再调用该类的构造函数，如果该类的构造函数有参数要求，则必须给出对应的实参。
 * 使用了delete释放某个重载了delete的累的对象空间时，先调用类的析构函数，然后再调用重载的delete函数。
*/

#include <cstdlib>

#include <iostream>

using namespace std;

class Foo
{
  public:
    Foo() : _id(0) { cout << "default ctor.this=" << this << " id=" << 0 << endl; }
    Foo(int i) : _id(i) { cout << "ctor.this=" << this << " id=" << i << endl; }
    ~Foo() { cout << "dtor.this = " << this << endl; }

    void *operator new(size_t size);
    void *operator new[](size_t size);

    void operator delete(void *ptr);
    void operator delete[](void *ptr);

  private:
    int _id;
    long _data;
    string _str;
};

void *Foo::operator new(size_t size)
{
    Foo *p = (Foo *)malloc(size);
    cout << "Member new(). size=" << size << endl;

    return p;
}

void *Foo::operator new[](size_t size)
{
    Foo *p = (Foo *)malloc(size);
    cout << "Member new()[]. size=" << size << endl;

    return p;
}

void Foo::operator delete(void *ptr)
{
    free(ptr);
    cout << "Member delete\n";
}

void Foo::operator delete[](void *ptr)
{
    free(ptr);
    cout << "Member delete[]\n";
}

int main()
{
    cout << "Size Foo=" << sizeof(Foo) << endl;

    Foo *fp = new Foo();
    Foo *fp1 = new Foo(1);

    Foo *array = new Foo[4];

    delete fp;
    delete fp1;

    delete[] array;


    Foo *df = ::new Foo();
    ::delete df;

    return 0;
}